package com.uzai.console.service.mini.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.uzai.common.exception.BusinessException;
import com.uzai.common.result.ResponseCode;
import com.uzai.console.common.utils.DateUtil;
import com.uzai.console.common.utils.Tools;
import com.uzai.console.config.UzaiConsoleSysConfig;
import com.uzai.console.dto.mini.minicode.MiniCodeDto;
import com.uzai.console.dto.mini.minicode.MiniCodeIdDto;
import com.uzai.console.dto.mini.minicode.MiniCodeQuery;
import com.uzai.console.dto.mini.minicode.MiniCodeRefreshDto;
import com.uzai.console.entity.DeviceMiniInfo;
import com.uzai.console.entity.MiniCode;
import com.uzai.console.entity.MiniComponentAuth;
import com.uzai.console.jsonvo.mini.*;
import com.uzai.console.mapper.DeviceMiniInfoMapper;
import com.uzai.console.mapper.MiniCodeMapper;
import com.uzai.console.mapper.MiniComponentAuthMapper;
import com.uzai.console.service.mini.MiniCodeService;
import com.uzai.console.service.mini.MiniOptService;
import com.uzai.console.vo.mini.minicode.MiniCodeVo;
import com.uzai.console.vo.mini.minicode.MiniTemplateVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @author liuqi
 * @date 2021年08月23日 20:25
 */
@Service
public class MiniCodeServiceImpl implements MiniCodeService {

    Logger logger = LoggerFactory.getLogger(MiniCodeServiceImpl.class);


    @Autowired
    private MiniCodeMapper miniCodeMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private MiniOptService miniOptService;
    @Autowired
    private UzaiConsoleSysConfig uzaiConsoleSysConfig;
    @Autowired
    private DeviceMiniInfoMapper deviceMiniInfoMapper;
    @Autowired
    private MiniComponentAuthMapper miniComponentAuthMapper;

    /**
     * 分页查询小程序团购商品列表
     * @author liuqi
     * @date 2021/8/13 11:38
     * @return MiniCodeVo
     */
    public Page<MiniCodeVo> findMiniCodeByPage(MiniCodeQuery miniCodeQuery){
        //新建返回到页面的LIST对象
        List<MiniCodeVo> miniCodeVoList = new ArrayList<>();
        //返回到页面分页对象
        Page<MiniCodeVo> pageVo = new Page<>();

        //执行分页查询对象
        Page<MiniCode> page = new Page<>();
        miniCodeQuery.convert(page);
        List<MiniCode> miniCodeList = miniCodeMapper.findByList(page, miniCodeQuery);

        if(miniCodeList != null && miniCodeList.size() > 0){
            for (MiniCode miniCode : miniCodeList){
                MiniCodeVo miniCodeVo = new MiniCodeVo();
                BeanUtils.copyProperties(miniCode, miniCodeVo);
                miniCodeVoList.add(miniCodeVo);

                //查询有审核中的代码版本，自动去获取审核结果
                if(Tools.getInteger(miniCode.getStatus()).intValue() == 1 && miniCode.getAuditid() != null){
                    //获取授权令牌
                    MiniComponentAuth miniComponentAuth = miniComponentAuthMapper.selectByAuthorizerAppid(miniCode.getMiniAppId());
                    if(miniComponentAuth != null){
                        GetAuditStatusResult getAuditStatusResult = miniOptService.getAuditStatus(miniComponentAuth.getAuthorizerAccessToken(), miniCode.getAuditid());
                        if(getAuditStatusResult != null && getAuditStatusResult.getErrcode() == 0){ //查询成功
                            //审核状态0-审核成功;1-审核被拒绝;2-审核中;3-已撤回;4-审核延后
                            Integer status = Tools.getInteger(getAuditStatusResult.getStatus());
                            if(status == 0){ //审核成功
                                miniCode.setStatus(2); //已审核
                                miniCode.setUpdateTime(DateUtil.getNowTime());
                                miniCodeMapper.updateByIdSelective(miniCode);
                                //清空小程序授权信息中中的在审核代码版本
                                DeviceMiniInfo deviceMiniInfo = deviceMiniInfoMapper.selectByAppId(miniCode.getMiniAppId());
                                if(deviceMiniInfo != null){
                                    deviceMiniInfo.setCodeVersionCheck(null);
                                    deviceMiniInfo.setUpdateTime(DateUtil.getNowTime());
                                    deviceMiniInfoMapper.updateCodeVersionById(deviceMiniInfo);
                                }
                            }else if(status == 1 || status == 3){
                                miniCode.setStatus(3); //审核失败
                                miniCode.setMsg(getAuditStatusResult.getReason());
                                miniCode.setUpdateTime(DateUtil.getNowTime());
                                miniCodeMapper.updateByIdSelective(miniCode);
                                //清空小程序授权信息中中的在审核代码版本
                                DeviceMiniInfo deviceMiniInfo = deviceMiniInfoMapper.selectByAppId(miniCode.getMiniAppId());
                                if(deviceMiniInfo != null){
                                    deviceMiniInfo.setCodeVersionCheck(null);
                                    deviceMiniInfo.setUpdateTime(DateUtil.getNowTime());
                                    deviceMiniInfoMapper.updateCodeVersionById(deviceMiniInfo);
                                }
                            }
                        }
                    }
                }

            }
        }

        BeanUtils.copyProperties(page, pageVo);
        pageVo.setRecords(miniCodeVoList);
        //将分页信息复制到返回到页面的分页MO当中
        return pageVo;
    }

    /**
     * 查询小程序团购商品详情
     * @author liuqi
     * @date 2021/8/13 11:38
     * @return MiniCodeVo
     */
    public MiniCodeVo findMiniCodeById(MiniCodeIdDto miniCodeIdDto){

        //返回的对象
        MiniCodeVo miniCodeVo = new MiniCodeVo();

        if(miniCodeIdDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id");
        }

        MiniCode miniCode = miniCodeMapper.selectById(miniCodeIdDto.getId(), miniCodeIdDto.getMerId());
        if(miniCode == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该记录不存在");
        }

        BeanUtils.copyProperties(miniCode, miniCodeVo);

        return miniCodeVo;
    }

    /**
     * 修改小程序团购商品详情
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param miniCodeDto
     * @return null
     */
    @Transactional
    public void addMiniCode(MiniCodeDto miniCodeDto){
        int now = DateUtil.getNowTime();
        MiniCode miniCode = new MiniCode();
        miniCode.setId(IdWorker.getId());
        miniCode.setMerId(miniCodeDto.getMerId());
        miniCode.setTemplateId(miniCodeDto.getTemplateId());
        miniCode.setName(miniCodeDto.getName());
        miniCode.setVersion(miniCodeDto.getVersion());
        miniCode.setDesc(miniCodeDto.getDesc());
        miniCode.setUpload(1);  //默认未上传代码
        miniCode.setStatus(0);  //默认未审核
        miniCode.setMsg(null);
        miniCode.setRemark(null);
        miniCode.setCreateTime(now);
        miniCode.setUpdateTime(now);
        miniCodeMapper.insertSelective(miniCode);
    }

    /**
     * 修改小程序团购商品详情
     * @author liuqi
     * @date 2021/8/13 11:38
     * @param miniCodeDto
     * @return null
     */
    public void updateMiniCode(MiniCodeDto miniCodeDto){

        if(miniCodeDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id");
        }

        MiniCode miniCode = miniCodeMapper.selectById(miniCodeDto.getId(), miniCodeDto.getMerId());

        if(miniCode == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该记录不存在");
        }

        int now = DateUtil.getNowTime();

        miniCode.setTemplateId(miniCodeDto.getTemplateId());
        miniCode.setName(miniCodeDto.getName());
        miniCode.setVersion(miniCodeDto.getVersion());
        miniCode.setDesc(miniCodeDto.getDesc());
        miniCode.setUpdateTime(now);
        miniCodeMapper.updateById(miniCode);
    }

    /**
     * 删除小程序团购商品信息
     * @author liuqi
     * @date 2021/8/13 11:38
     * @return null
     */
    public void deleteMiniCode(MiniCodeIdDto miniCodeIdDto){
        if(miniCodeIdDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id");
        }

        MiniCode miniCode = miniCodeMapper.selectById(miniCodeIdDto.getId(), miniCodeIdDto.getMerId());

        if(miniCode == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该记录不存在");
        }

        miniCodeMapper.deleteById(miniCodeIdDto.getId(), miniCodeIdDto.getMerId());
    }

    /**
     * 查询地址区域列表
     * @author liuqi
     * @date 2021/8/13 11:38
     * @return null
     */
    public List<MiniTemplateVo> fingMiniTemplateList(){
        //只显示第三方默认小程序的模板
        String miniComponentTemplateAppid = uzaiConsoleSysConfig.getMiniComponentTemplateAppid();
        List<MiniTemplateVo> miniTemplateVoList = new ArrayList<>();
        //获取第三方token
        String access_token = miniOptService.getComponentAccessToken();
        if(access_token == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "未获取到第三方平台令牌");
        }

        //查询普通模板
        MiniTemplate miniTemplate = miniOptService.getTemplateList(access_token, 0);
        if(miniTemplate != null){
            List<MiniTemplate.Template> template_list = miniTemplate.getTemplate_list();
            if(template_list != null && template_list.size() > 0){
                for (MiniTemplate.Template template : template_list) {
                    //匹配到默认的小程序
                    if(miniComponentTemplateAppid.equals(template.getSource_miniprogram_appid())){
                        MiniTemplateVo miniTemplateVo = new MiniTemplateVo();
                        miniTemplateVo.setTemplateId(template.getTemplate_id());
                        miniTemplateVo.setVersion(template.getUser_version());
                        miniTemplateVo.setDesc(template.getUser_desc());
                        miniTemplateVoList.add(miniTemplateVo);
                    }
                }
            }
        }
        return miniTemplateVoList;
    }

    /**
     * 小程序代码管理刷新最新版本
     * @author liuqi
     * @date 2021/8/13 11:38
     * @return null
     */
    public void refreshMiniCode(MiniCodeRefreshDto miniCodeRefreshDto){
        if(StringUtils.isBlank(miniCodeRefreshDto.getMiniAppId())){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入小程序appid");
        }

        DeviceMiniInfo deviceMiniInfo = deviceMiniInfoMapper.selectByAppId(miniCodeRefreshDto.getMiniAppId());
        if(deviceMiniInfo == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该小程序不存在");
        }

        //查询系统最新代码版本
        MiniCode miniCode_newest_system = miniCodeMapper.selectNewestAndUpload(8888L);
        if(miniCode_newest_system == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "系统目前没有最新版");
        }

        //查询该最新版本是否已经在该小程序代码当中
        MiniCode miniCode_newest_mini = miniCodeMapper.selectByTemplateIdAndMiniAppId(miniCode_newest_system.getTemplateId(), deviceMiniInfo.getMiniAppId());
        if(miniCode_newest_mini != null ){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该小程序已经有系统最新版本");
        }

        //刷新系统最新版本
        int now = DateUtil.getNowTime();
        miniCode_newest_mini = new MiniCode();
        miniCode_newest_mini.setId(IdWorker.getId());
        miniCode_newest_mini.setMerId(deviceMiniInfo.getMerId());
        miniCode_newest_mini.setMiniAppId(deviceMiniInfo.getMiniAppId());
        miniCode_newest_mini.setTemplateId(miniCode_newest_system.getTemplateId());
        miniCode_newest_mini.setName(miniCode_newest_system.getName());
        miniCode_newest_mini.setVersion(miniCode_newest_system.getVersion());
        miniCode_newest_mini.setDesc(miniCode_newest_system.getDesc());
        miniCode_newest_mini.setUpload(1);  //默认已上传代码
        miniCode_newest_mini.setStatus(0);  //默认未审核
        miniCode_newest_mini.setMsg(null);
        miniCode_newest_mini.setRemark(null);
        miniCode_newest_mini.setCreateTime(now);
        miniCode_newest_mini.setUpdateTime(now);
        miniCodeMapper.insertSelective(miniCode_newest_mini);
    }

    /**
     * 小程序代码管理提交审核
     * @author liuqi
     * @date 2021/8/13 11:38
     * @return null
     */
    public void checkMiniCode(MiniCodeIdDto miniCodeIdDto){
        if(miniCodeIdDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id");
        }

        MiniCode miniCode = miniCodeMapper.selectById(miniCodeIdDto.getId(), miniCodeIdDto.getMerId());

        if(miniCode == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该记录不存在");
        }

        DeviceMiniInfo deviceMiniInfo = deviceMiniInfoMapper.selectByAppId(miniCode.getMiniAppId());
        if(deviceMiniInfo == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该小程序不存在");
        }

        //获取授权令牌
        MiniComponentAuth miniComponentAuth = miniComponentAuthMapper.selectByAuthorizerAppid(miniCode.getMiniAppId());
        if(miniComponentAuth == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该小程序授权令牌不存在");
        }

        //1-设置小程序服务器域名
        String miniServerDomain = uzaiConsoleSysConfig.getMiniServerDomain();
        List<String> domainList = new ArrayList<>();
        domainList.add(miniServerDomain);
        List tempList = new ArrayList<>();
        ModifyServerDomainResult modifyServerDomainResult = miniOptService.modifyServerDomain(miniComponentAuth.getAuthorizerAccessToken(), "add", domainList, tempList, domainList, domainList, tempList, tempList);
        if (modifyServerDomainResult == null || modifyServerDomainResult.getErrcode() != 0) {
            logger.error("--设置小程序域名失败--appId={}, domain={},msg={}", deviceMiniInfo.getMiniAppId(), miniServerDomain, modifyServerDomainResult.getErrmsg());
        }
        //2-设置小程序用户隐私保护指引
        Integer privacy_ver = 2;//用户隐私保护指引的版本，1表示现网版本；2表示开发版。默认是2开发版
        MiniBaseResult miniBaseResultprivactSetting = miniOptService.setPrivacySetting(miniComponentAuth.getAuthorizerAccessToken(), privacy_ver, MiniPrivacySettingEnum.getSettingList(), MiniPrivacySettingEnum.getOwnerSetting(), null);
        if (miniBaseResultprivactSetting == null || miniBaseResultprivactSetting.getErrcode() != 0) {
            logger.error("--设置小程序用户隐私保护指引失败--appId={}, domain={}，msg={}", deviceMiniInfo.getMiniAppId(), miniServerDomain, miniBaseResultprivactSetting.getErrmsg());
        }
        //3-获取小程序类目
        GetAllCategoryNameResult getAllCategoryNameResult = miniOptService.getAllCategoryName(miniComponentAuth.getAuthorizerAccessToken());
        if (getAllCategoryNameResult == null || getAllCategoryNameResult.getErrcode() != 0) {
            logger.error("--查询小程序类目信息失败--appId={},msg={}", deviceMiniInfo.getMiniAppId(), miniBaseResultprivactSetting.getErrmsg());
        }
        //4-代码审核
        List<JSONObject> item_list = new ArrayList<>();
        if (getAllCategoryNameResult != null && getAllCategoryNameResult.getErrcode() == 0) {
            List<GetAllCategoryNameResult.Category> categoryList = getAllCategoryNameResult.getCategory_list();
            if (categoryList != null && categoryList.size() > 0) {
                for (GetAllCategoryNameResult.Category category : categoryList) {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("first_class", category.getFirst_class());
                    jsonObject.put("first_id", category.getFirst_id());
                    jsonObject.put("second_class", category.getSecond_class());
                    jsonObject.put("second_id", category.getSecond_id());
                    item_list.add(jsonObject);
                }
            }
        }

        int now = DateUtil.getNowTime();

        SubmitAuditResult submitAuditResult = miniOptService.submitAudit(miniComponentAuth.getAuthorizerAccessToken(), item_list);
        if (submitAuditResult != null && submitAuditResult.getErrcode() == 0 && submitAuditResult.getAuditid() != null) {
            //提交代码审核成功，则修改小程序信息表
            deviceMiniInfo.setCodeVersionCheck(miniCode.getVersion());
            deviceMiniInfo.setUpdateTime(now);
            deviceMiniInfoMapper.updateCodeVersionById(deviceMiniInfo);
            //修改小程序代码管理表
            miniCode.setAuditid(submitAuditResult.getAuditid());
            miniCode.setStatus(1); //审核中
            miniCode.setUpdateTime(now);
            miniCodeMapper.updateByIdSelective(miniCode);
        }else{
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, StringUtils.isNotBlank(submitAuditResult.getErrmsg())?submitAuditResult.getErrmsg():"提交审核失败");
        }
    }

    /**
     * 小程序代码管理发布版本
     * @author liuqi
     * @date 2021/8/13 11:38
     * @return null
     */
    public void releaseMiniCode(MiniCodeIdDto miniCodeIdDto){
        if(miniCodeIdDto.getId() == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入id");
        }

        MiniCode miniCode = miniCodeMapper.selectById(miniCodeIdDto.getId(), miniCodeIdDto.getMerId());

        if(miniCode == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该记录不存在");
        }

        DeviceMiniInfo deviceMiniInfo = deviceMiniInfoMapper.selectByAppId(miniCode.getMiniAppId());
        if(deviceMiniInfo == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该小程序不存在");
        }

        //获取授权令牌
        MiniComponentAuth miniComponentAuth = miniComponentAuthMapper.selectByAuthorizerAppid(miniCode.getMiniAppId());
        if(miniComponentAuth == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该小程序授权令牌不存在");
        }

        //发布版本
        MiniBaseResult miniBaseResult = miniOptService.release(miniComponentAuth.getAuthorizerAccessToken());
        if(miniBaseResult != null && miniBaseResult.getErrcode() == 0){
            //提交代码发布成功，则修改小程序已发布版本信息字段
            deviceMiniInfo.setCodeVersionRelease(miniCode.getVersion());
            deviceMiniInfo.setUpdateTime(DateUtil.getNowTime());
            deviceMiniInfoMapper.updateCodeVersionById(deviceMiniInfo);

            miniCode.setStatus(4);//已发布
            miniCode.setUpdateTime(DateUtil.getNowTime());
            miniCodeMapper.updateByIdSelective(miniCode);
        }else{
            logger.error("发布版本失败，error={}", miniBaseResult.getErrmsg());
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, StringUtils.isNotBlank(miniBaseResult.getErrmsg())?miniBaseResult.getErrmsg():"发布失败");
        }
    }

    /**
     * 查询小程序代码管理最新版本信息
     * @author liuqi
     * @date 2021/8/13 11:38
     * @return null
     */
    public MiniCodeVo findNewestByAppId(MiniCodeRefreshDto miniCodeRefreshDto){
        MiniCodeVo miniCodeVo = new MiniCodeVo();

        if(StringUtils.isBlank(miniCodeRefreshDto.getMiniAppId())){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "请输入小程序appid");
        }

        DeviceMiniInfo deviceMiniInfo = deviceMiniInfoMapper.selectByAppId(miniCodeRefreshDto.getMiniAppId());
        if(deviceMiniInfo == null){
            throw  new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "该小程序不存在");
        }

        MiniCode miniCode = miniCodeMapper.selectNewestAndUploadByAppId(miniCodeRefreshDto.getMiniAppId());
        if(miniCode != null){
            BeanUtils.copyProperties(miniCode, miniCodeVo);
        }

        return miniCodeVo;
    }

}
